package com.qf.flashlib.net;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import com.qf.flashlib.app.BaseApp;
import com.qf.flashlib.config.Constants;
import com.qf.flashlib.http.LoggerUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 2019/3/27 14:29
 */
public class NetWorkReceiver extends BroadcastReceiver {


    private Map<Object, List<MethodManager>> netMap;

    public NetWorkReceiver() {
        this.netMap = new HashMap<>();
    }

    private int lastType; //解决网络变化是多次接收到广播的问题

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent == null || intent.getAction() == null)
            return;
        if (intent.getAction().equalsIgnoreCase(Constants.ANDROID_NET_CHANGE_ACTION)) {
            int type = NetworkUtil.getNetworkType(BaseApp.getInstance());
            if (type == lastType) {
                return;
            }
            lastType = type;
            post(type);
        }
    }

    private void post(int type) {
        Set<Object> keySet = netMap.keySet();
        for (Object getter : keySet) {
            List<MethodManager> methodManagers = netMap.get(getter);
            for (MethodManager methodManager : methodManagers) {
                //对被注解的method方法的校验
                if (methodManager.getTarget().isAssignableFrom(NetType.class)) {
                    invoke(methodManager, getter, type);
                }
            }
        }

    }

    private void invoke(MethodManager methodManager, Object getter, int type) {
        Method method = methodManager.getMethod();
        if (methodManager.getNetType() == type ) {
            try {
                method.invoke(getter, new NetType(type));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }

    }


    public void registerObserver(Object target) {
        List<MethodManager> methodList = netMap.get(target);
        if (methodList == null) {
            //开始添加
            methodList = findMethodListWithAnnotation(target);
            netMap.put(target, methodList);
        }
    }

    private List<MethodManager> findMethodListWithAnnotation(Object target) {
        List<MethodManager> list = new ArrayList<>();
        Class<?> aClass = target.getClass();
        //获取target中的所有的方法
        try {
            Method[] methods = aClass.getDeclaredMethods();
            for (Method method : methods) {
                //获取方法的注解
                NetWork annotation = method.getAnnotation(NetWork.class);
                if (annotation == null){
                    continue;
                }
                //注解方法的校验
                Class<?> returnType = method.getReturnType();
                if (!"void".equalsIgnoreCase(returnType.toString())) {
                    LoggerUtil.e(method.getName() + "方法的返回类型不是void");
                    throw new RuntimeException(method.getName() + "方法的返回类型不是void");
                }
                Class<?>[] parameterTypes = method.getParameterTypes();
                if (parameterTypes.length != 1) {
                    LoggerUtil.e(method.getName() + "方法只能有一个参数");
                    throw new RuntimeException(method.getName() + "方法只能有一个参数");
                }
                MethodManager methodManager = new MethodManager(parameterTypes[0], method, annotation.netType());
                list.add(methodManager);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return list;
    }

    public void unRegisterObserver(Object target) {
        if (!netMap.isEmpty()) {
            netMap.remove(target);
            LoggerUtil.d("移除了============" + target.getClass().getName());
        }
    }


    public void unRegisterAllObserver() {
        if (!netMap.isEmpty()) {
            netMap.clear();
            LoggerUtil.d("清空网络监听============");
        }
    }
}
